﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace UIKit.Controls
{
    public abstract class BaseControl : Control
    {
        #region Fields
        internal const char VisualStateDelimiter = ',';
        internal bool changePropertySilently;
        private bool isFocused;
        private bool isLoaded;
        private bool isTemplateApplied;
        private byte visualStateUpdateLock;
        private string currentVisualState;
        #endregion

        #region Properties
        public string CurrentVisualState
        {
            get
            {
                return this.currentVisualState;
            }
        }

        public bool IsLoaded
        {
            get
            {
                return this.isLoaded;
            }
        }

        public bool IsTemplateApplied
        {
            get
            {
                return this.isTemplateApplied;
            }
        }

        protected internal virtual bool IsPropertyTemplated
        {
            get
            {
                return this.isTemplateApplied;
            }
        }
        #endregion

        #region DependencyProperties
        public bool IsFocused
        {
            get
            {
                return this.isFocused;
            }
            protected set { SetValue(IsFocusedProperty, value); }
        }

        public static readonly DependencyProperty IsFocusedProperty =
            DependencyProperty.Register("IsFocused", typeof(bool), typeof(BaseControl), new PropertyMetadata(OnIsFocusChanged));

        private static void OnIsFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            BaseControl ctrl = (BaseControl)d;
            ctrl.isFocused = (bool)e.NewValue;
            ctrl.UpdateVisualState(ctrl.isLoaded);
        }



        public object InnerDataContext
        {
            get { return (object)GetValue(InnerDataContextProperty); }
            set { SetValue(InnerDataContextProperty, value); }
        }

        public static readonly DependencyProperty InnerDataContextProperty =
            DependencyProperty.Register("InnerDataContext", typeof(object), typeof(BaseControl), new PropertyMetadata(OnInnerDataContextChanged));

        private static void OnInnerDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            BaseControl ctrl = (BaseControl)d;
            ctrl.OnDataContextChanged();
        }

        #endregion

        #region Constructor
        public BaseControl()
        {
            this.Loaded += new RoutedEventHandler(BaseControl_Loaded);
            this.Unloaded += new RoutedEventHandler(BaseControl_Unloaded);
            this.currentVisualState = string.Empty;
            base.SetBinding(InnerDataContextProperty, new Binding());
        }

        #endregion

        #region ApplyTemplate
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.isTemplateApplied = true;
        }
        #endregion


        #region Event
        protected virtual void BaseControl_Loaded(object sender, RoutedEventArgs e)
        {
            this.isLoaded = true;
        }

        protected virtual void BaseControl_Unloaded(object sender, RoutedEventArgs e)
        {
            this.isLoaded = false;
        }
        #endregion

        #region Method

        #region Internal
        protected internal void BeginVisualStateUpdate()
        {
            this.visualStateUpdateLock += 1;
        }

        protected internal void EndVisualStateUpdate(bool update,bool animate)
        {
            if (this.visualStateUpdateLock > 0)
            {
                this.visualStateUpdateLock -= 1;
            }
            if (update && this.visualStateUpdateLock == 0)
            {
                this.UpdateVisualState(animate);
            }
        }

        protected internal void UpdateVisualState(bool animate)
        {
            if (!this.CanUpdateVisualState())
            {
                return;
            }
            string visualStateName = this.ComposeVisualStateName();
            if (visualStateName != this.currentVisualState)
            {
                this.currentVisualState = visualStateName;
                this.SetVisualState(visualStateName, animate);
            }
        }

        #endregion

        #region VirtualMethod
        /// <summary>
        /// 判断是否可以更新状态
        /// </summary>
        /// <returns></returns>
        protected virtual bool CanUpdateVisualState()
        {
            return this.isTemplateApplied && this.visualStateUpdateLock == 0;
        }
        /// <summary>
        /// 获取当前状态的名称
        /// </summary>
        /// <returns></returns>
        protected virtual string ComposeVisualStateName()
        {
            return string.Empty;
        }
        /// <summary>
        /// 设置当前的状态
        /// </summary>
        /// <param name="state"></param>
        /// <param name="animate"></param>
        /// <returns></returns>
        protected virtual void SetVisualState(string state, bool animate)
        {
            string[] array = state.Split(',');
            string[] array2 = array;
            foreach (var stateName in array2)
            {
                VisualStateManager.GoToState(this, stateName, animate);
            }
        }

        protected virtual void OnDataContextChanged()
        {
            throw new NotImplementedException();
        }
        #endregion

        #endregion
    }
}
